package cn.edu.xmu.oomall.order.service;

import cn.edu.xmu.oomall.core.util.ReturnNo;
import cn.edu.xmu.oomall.core.util.ReturnObject;
import cn.edu.xmu.oomall.order.dao.OrderDao;
import cn.edu.xmu.oomall.order.dao.OrderItemDao;
import cn.edu.xmu.oomall.order.dao.PaymentDao;
import cn.edu.xmu.oomall.order.dao.RefundDao;
import cn.edu.xmu.oomall.order.microservice.*;
import cn.edu.xmu.oomall.order.model.bo.Refund;
import cn.edu.xmu.oomall.order.microservice.vo.*;
import cn.edu.xmu.oomall.order.model.bo.Order;
import cn.edu.xmu.oomall.order.model.bo.OrderItem;
import cn.edu.xmu.oomall.order.model.bo.Payment;
import cn.edu.xmu.oomall.order.model.po.*;
import cn.edu.xmu.oomall.order.model.vo.*;
import cn.edu.xmu.oomall.order.util.ValidList;
import cn.edu.xmu.privilegegateway.annotation.aop.LoginName;
import cn.edu.xmu.privilegegateway.annotation.aop.LoginUser;
import cn.edu.xmu.privilegegateway.annotation.util.Common;
import cn.edu.xmu.privilegegateway.annotation.util.InternalReturnObject;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import net.bytebuddy.asm.Advice;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.PathVariable;

import java.time.LocalDateTime;
import java.util.*;

import static cn.edu.xmu.privilegegateway.annotation.util.Common.cloneVo;

@Service
public class OrderService {
    @Autowired
    private OrderDao orderDao;
    @Autowired
    private OrderItemDao orderItemDao;
    @Autowired
    private PaymentDao paymentDao;
    @Autowired
    private RefundDao refundDao;
    @Autowired
    private PrivilegeService privilegeService;
    @Autowired
    private ShopService shopService;
    @Autowired
    private GoodsService goodsService;
    @Autowired
    private FreightService freightService;
    @Autowired
    private CouponService couponService;
    @Autowired
    private CustomerService customerService;
    @Autowired
    private OrderItemService orderItemService;
    @Autowired
    private PaymentService paymentService;
    @Autowired
    private AdvanceSaleService advanceSaleService;
    @Autowired
    private GroupOnActivityService groupOnActivityService;


    /**
     * 查询自己订单的支付信息
     * @param id
     * @return ReturnObject
     */
    @Transactional(readOnly = true, rollbackFor = Exception.class)
    public ReturnObject getOrderPayments(Long id) {
        PaymentPoExample paymentPoExample = new PaymentPoExample();
        PaymentPoExample.Criteria criteria = paymentPoExample.createCriteria();
        criteria.andDocumentIdEqualTo(String.valueOf(id));

        return orderDao.getOrderPayments(paymentPoExample);
    }


    /**
     * 获取订单所有状态
     */
    @Transactional(readOnly = true, rollbackFor = Exception.class)
    public ReturnObject getOrderState() {
        return orderDao.getOrderState();
    }

//==================================买家=============================================


    /**
     * 买家查看名下订单（概要）
     */
    @Transactional(readOnly = true, rollbackFor = Exception.class)
    public ReturnObject selectSimpleOrder(Long userId, String orderSn, Integer state, LocalDateTime beginTime, LocalDateTime endTime, Integer page, Integer pageSize) {
        OrderPoExample example = new OrderPoExample();
        OrderPoExample.Criteria criteria = example.createCriteria();
        example.setOrderByClause("gmt_create desc");
        criteria.andCustomerIdEqualTo(userId);
        criteria.andBeDeletedEqualTo((byte) 0);
        if (orderSn != null)
            criteria.andOrderSnEqualTo(orderSn);
        if (state != null) {
            if (state == 200) {
                // 200是范围大类
                criteria.andStateEqualTo(201);
            } else {
                criteria.andStateEqualTo(state);
            }
        }
        if (beginTime != null)
            criteria.andGmtCreateGreaterThan(beginTime);
        if (endTime != null)
            criteria.andGmtCreateLessThan(endTime);
        List<Order> orders = (List<Order>) orderDao.selectOrders(example).getData();
        if (orders == null)
            return new ReturnObject(ReturnNo.RESOURCE_ID_NOTEXIST);
        List<OrderInfoSimpleVo> orderInfoSimpleVos = new ArrayList<>(orders.size());
        for (Order order : orders) {
            orderInfoSimpleVos.add(cloneVo(order, OrderInfoSimpleVo.class));
        }
        PageHelper.startPage(page, pageSize);
        PageInfo<OrderInfoSimpleVo> pageInfo = new PageInfo<OrderInfoSimpleVo>(orderInfoSimpleVos);
        return new ReturnObject(pageInfo);
    }

    /**
     * 买家申请建立订单
     */
    //使用优惠券没写
    @Transactional(rollbackFor = Exception.class)
    public ReturnObject insertOrder(OrderVo orderVo, Long userId, String userName) {
        List<OrderItemDiscountVo> orderItemDiscountVos = new ArrayList<>();
        List<OrderItemVo> orderItemVos = orderVo.getOrderItems();
        Map<Long, List<OrderItemVo>> map = new HashMap<>();
        //按照shopId 对OrderItemVo分组
        for (OrderItemVo orderItemVo : orderItemVos) {
            ProductRetVo productRetVo = goodsService.getProductDetails(orderItemVo.getProductId()).getData();

            // 添加优惠活动计算表
            OrderItemDiscountVo discountVo = new OrderItemDiscountVo();
            discountVo.setProductId(orderItemVo.getProductId());
            discountVo.setOnsaleId(orderItemVo.getOnsaleId());
            discountVo.setQuantity(orderItemVo.getQuantity());
            discountVo.setActivityId(orderItemVo.getCouponActivityId());
            discountVo.setOriginalPrice(productRetVo.getPrice());
            orderItemDiscountVos.add(discountVo);

            // 根据店铺分单
            if (null == productRetVo) {
                return new ReturnObject(ReturnNo.RESOURCE_ID_NOTEXIST);
            }
            Long shopId = productRetVo.getShop().getId();
            List<OrderItemVo> itemVos;
            if (map.containsKey(shopId)) {
                itemVos = map.get(shopId);
            } else {
                itemVos = new ArrayList<>();
            }
            itemVos.add(orderItemVo);
            System.out.println(orderItemVo);
            map.put(shopId, itemVos);
        }
        //为每一分组创建子订单
        Set<Long> shopIdSet = map.keySet();
        Iterator<Long> it = shopIdSet.iterator();
        Long parentShopId = 0L;
        Long pId = 0L;

        // 获取折扣信息
        InternalReturnObject discountReturnObject = couponService.discountPrice(orderItemDiscountVos);
        if (!discountReturnObject.getErrno().equals(0)) {
            return new ReturnObject(ReturnNo.getReturnNoByCode(discountReturnObject.getErrno()), discountReturnObject.getErrmsg());
        }
        List<OrderItemDiscountRetVo> discountRetVos = (List<OrderItemDiscountRetVo>) discountReturnObject.getData();
        // 对返回的折扣信息进行合并参数
        Map<Long, OrderItemDiscountRetVo> discountRetVoMap = new HashMap<>();
        for (OrderItemDiscountRetVo discountRetVo : discountRetVos) {
            discountRetVoMap.put(discountRetVo.getProductId(), discountRetVo);
        }

        //不需要分单，设置shopId
        if (shopIdSet.size() == 1) {
            parentShopId = it.next();
            ReturnObject ret = createOrder(pId, orderItemVos, orderVo, parentShopId, userId, userName, discountRetVoMap);
            if (ret.getCode().getCode() != 0) {
                return ret;
            }
            OrderRetVo parentOrder = (OrderRetVo) ret.getData();
            pId = parentOrder.getId();
        } else {
            ReturnObject ret = createParentOrder(orderVo,userId, userName);
            OrderPo parentOrder = (OrderPo) ret.getData();
            pId = parentOrder.getId();

            Long parentOriginPrice = 0L;
            Long parentDiscountPrice = 0L;
            Long expressFee = 0L;
            List<OrderItem> orderItemsTotal = new ArrayList<>();

            //创建子订单
            while (it.hasNext()) {
                Long shopId = it.next();
                List<OrderItemVo> orderItemChildVos = map.get(shopId);
                ReturnObject childRet = createChildOrder(pId, orderItemChildVos, orderVo, shopId, userId, userName, discountRetVoMap, orderItemsTotal);
                if (childRet.getCode().getCode() != 0) {
                    return new ReturnObject(ReturnNo.INTERNAL_SERVER_ERR);
                }
                OrderRetVo orderRetVo = (OrderRetVo) childRet.getData();
                parentOriginPrice += orderRetVo.getOriginPrice();
                parentDiscountPrice += orderRetVo.getDiscountPrice();
                expressFee += orderRetVo.getExpressFee();
            }

            Long freightPrice = ((FreightCalculatingRetVo) orderItemService.calculateFreight(orderVo.getRegionId(), orderItemsTotal).getData()).getFreightPrice();

            //更新父订单
            Order order = (Order) orderDao.selectOrderById(pId).getData();
            order.setOriginPrice(parentOriginPrice);
            order.setDiscountPrice(parentDiscountPrice);
            order.setExpressFee(freightPrice);
            ReturnObject updateRet = orderDao.updateOrder(order);
            if (updateRet.getCode().getCode() != 0) {
                return ret;
            }
            Long parentAmount = parentOriginPrice - parentDiscountPrice - order.getPoint() + expressFee;
            Long allPoint = order.getPoint() - expressFee;
            if (allPoint > 0L) {
                List<Order> orders = orderDao.selectChildOrders(pId).getData();
                for (Order childOrder : orders) {
                    Long childAmount = childOrder.getOriginPrice() - childOrder.getDiscountPrice();
                    Long point = (childAmount / parentAmount) * allPoint;
                    childOrder.setPoint(point);
                    orderDao.updateOrder(childOrder);
                    //分摊积点到订单明细
                    List<OrderItem> orderItems = (List) orderItemDao.selectOrderItemsByOrderId(childOrder.getId()).getData();
                    for (OrderItem orderItem : orderItems) {
                        Long orderItemAmount = (orderItem.getPrice() - orderItem.getDiscountPrice()) * orderItem.getQuantity();
                        Long orderItemPoint = (orderItemAmount / parentAmount) * allPoint;
                        orderItem.setPoint(orderItemPoint);
                        orderItemDao.updateOrderItem(orderItem);
                    }

                }
            }
        }

        //返回支付信息，未生成支付订单
        Order order = (Order) orderDao.selectOrderById(pId).getData();
        Long amount = order.getOriginPrice() - order.getDiscountPrice() - order.getPoint() + order.getExpressFee();
        OrderPaymentRetVo retVo = new OrderPaymentRetVo(order.getOrderSn(), (byte) 0, null, amount, LocalDateTime.now(), LocalDateTime.now().plusDays(3));
        List<OrderPaymentRetVo> retVos = new ArrayList<>();
        retVos.add(retVo);

        CustomerVo customerVo = (CustomerVo) customerService.selectSelf().getData();
        if (customerVo == null)
            return new ReturnObject(ReturnNo.RESOURCE_ID_NOTEXIST);
        Long point = customerVo.getPoint();
        System.out.println(point);
        return new ReturnObject(retVos);
    }


    /**
     * 建立父订单
     */
    @Transactional(rollbackFor = Exception.class)
    public ReturnObject createParentOrder(OrderVo orderVo, Long userId, String userName) {
        //计算积点
        CustomerVo customerVo = (CustomerVo) customerService.selectSelf().getData();
        if (customerVo == null)
            return new ReturnObject(ReturnNo.RESOURCE_ID_NOTEXIST);
        Long point = customerVo.getPoint();
        if (point < orderVo.getPoint()){
            orderVo.setPoint(point);
        }
        customerService.usePoint(userId, orderVo.getPoint());

        //新建订单
        Order order = cloneVo(orderVo, Order.class);
        order.setPid(0L);
        order.setShopId(0L);
        order.setState(Order.State.CREATED.getCode());
        order.setBeDeleted((byte) 0);
        order.setExpressFee(0L);
        order.setCustomerId(userId);
        order.setOriginPrice(0L);
        order.setDiscountPrice(0L);
        order.setAdvancesaleId(0L);
        order.setGrouponId(0L);

        Random r = new Random();
        int platform = Math.abs(r.nextInt(36));
        String orderSn = Common.genSeqNum(platform);
        order.setOrderSn(orderSn);
        Common.setPoCreatedFields(order, userId, userName);
        System.out.println("创建父订单好了");
        ReturnObject orderRet = orderDao.insertOrder(order);
        return orderRet;
    }

    /**
     * 新建子订单
     */
    @Transactional(rollbackFor = Exception.class)
    public ReturnObject createChildOrder(Long pId, List<OrderItemVo> orderItemChildVos, OrderVo orderVo, Long shopId, Long userId, String userName, Map<Long, OrderItemDiscountRetVo> discountRetVoMap, List<OrderItem> orderItemsTotal) {
        List<OrderItem> orderItems = new ArrayList<>(orderItemChildVos.size());
        Long orderOriginPrice = 0L;
        Long orderDiscountPrice = 0L;

        for (OrderItemVo orderItemVo : orderItemChildVos) {
            //通过货品id得到货品详细信息
            ProductRetVo productRetVo = (ProductRetVo) goodsService.getProductDetails(orderItemVo.getProductId()).getData();
            Long originPrice = productRetVo.getPrice();
            orderOriginPrice += originPrice * orderItemVo.getQuantity();
            String name = productRetVo.getName();
            //扣库存
            QuantityVo quantityVo = new QuantityVo();
            quantityVo.setQuantity(orderItemVo.getQuantity());
            InternalReturnObject returnObject = goodsService.decreaseOnSale(orderItemVo.getOnsaleId(), quantityVo);
            if (!returnObject.getErrno().equals(0)) {
                return new ReturnObject(ReturnNo.getReturnNoByCode(returnObject.getErrno()), returnObject.getErrmsg());
            }

            // 扣除优惠券
            if(orderItemVo.getCouponId()!=null){
                customerService.useCoupon(orderItemVo.getCouponId());
            }

            //设置 OrderItem
            OrderItem orderItem = cloneVo(orderItemVo, OrderItem.class);
            orderItem.setCommented((byte) 0);
            orderItem.setName(name);
            orderItem.setPrice(originPrice);
            orderItem.setShopId(shopId);
            // 计算折扣
            if (discountRetVoMap.containsKey(orderItemVo.getProductId())) {
                Long discountPrice = discountRetVoMap.get(orderItemVo.getProductId()).getDiscountPrice();
                orderItem.setDiscountPrice(discountPrice);
                orderDiscountPrice += discountPrice * orderItem.getQuantity();
            }
            orderItems.add(orderItem);
            orderItemsTotal.add(orderItem);
        }
        // 计算总折扣
        orderDiscountPrice = Math.round(1.0 * orderDiscountPrice / 10);

        //新建订单
        Order order = cloneVo(orderVo, Order.class);
        order.setPoint(0L);
        order.setPid(pId);
        order.setShopId(shopId);
        order.setState(Order.State.CREATED.getCode());
        order.setBeDeleted((byte) 0);
        order.setExpressFee(0L);
        order.setCustomerId(userId);
        order.setOriginPrice(orderOriginPrice);
        order.setDiscountPrice(orderDiscountPrice);
        order.setAdvancesaleId(0L);
        order.setGrouponId(0L);

        //生成订单序号
        Random r = new Random();
        int platform = Math.abs(r.nextInt(36));
        String orderSn = Common.genSeqNum(36);
        order.setOrderSn(orderSn);
        Common.setPoCreatedFields(order, userId, userName);
        order.setGmtCreate(LocalDateTime.now());
        ReturnObject orderRet = orderDao.insertOrder(order);
        if (!orderRet.getCode().equals(ReturnNo.OK)) {
            return orderRet;
        }
        order = cloneVo(orderRet.getData(), Order.class);

        //新建订单详情
        for (OrderItem orderItem : orderItems) {
            orderItem.setOrderId(order.getId());
            //orderItem.setPoint((orderItem.getPrice() / order.getOriginPrice()) * order.getPoint());
            Common.setPoCreatedFields(orderItem, userId, userName);

            //新增订单详情
            ReturnObject orderItemRet = orderItemDao.insertOrderItem(orderItem);
            if (!orderItemRet.getCode().equals(ReturnNo.OK)) {
                return orderItemRet;
            }
        }

        Long amount = orderOriginPrice - orderDiscountPrice;

        OrderRetVo orderRetVo = new OrderRetVo(order.getId(), orderOriginPrice, orderDiscountPrice, 0L, amount);
        System.out.println(orderRetVo);
        return new ReturnObject(orderRetVo);
    }


    /**
     * 新建一个订单及其对应的订单详情
     */
    @Transactional(rollbackFor = Exception.class)
    public ReturnObject createOrder(Long pId, List<OrderItemVo> orderItemChildVos, OrderVo orderVo, Long shopId, Long userId, String userName, Map<Long, OrderItemDiscountRetVo> discountRetVoMap) {
        List<OrderItemDiscountVo> orderItemDiscountVos = new ArrayList<>(orderItemChildVos.size());
        List<OrderItem> orderItems = new ArrayList<>(orderItemChildVos.size());
        Long orderOriginPrice = 0L;
        Long orderDiscountPrice = 0L;


        System.out.println("订单开始：");
        for (OrderItemVo orderItemVo : orderItemChildVos) {
            //通过货品id得到货品详细信息
            ProductRetVo productRetVo = (ProductRetVo) goodsService.getProductDetails(orderItemVo.getProductId()).getData();
            Long originPrice = productRetVo.getPrice();
            orderOriginPrice += originPrice * orderItemVo.getQuantity();
            String name = productRetVo.getName();
            //扣库存
            QuantityVo quantityVo = new QuantityVo();
            quantityVo.setQuantity(orderItemVo.getQuantity());
            InternalReturnObject returnObject = goodsService.decreaseOnSale(orderItemVo.getOnsaleId(), quantityVo);
            if (!returnObject.getErrno().equals(0)) {
                return new ReturnObject(ReturnNo.getReturnNoByCode(returnObject.getErrno()), returnObject.getErrmsg());
            }
            //获取需计算折扣的订单明细
            OrderItemDiscountVo discountVo = cloneVo(orderItemVo, OrderItemDiscountVo.class);
            discountVo.setActivityId(orderItemVo.getCouponActivityId());
            discountVo.setOriginalPrice(originPrice);
            orderItemDiscountVos.add(discountVo);

            //扣除优惠券
            if(orderItemVo.getCouponId()!=null){
                customerService.useCoupon(orderItemVo.getCouponId());
            }

            //设置 OrderItem
            OrderItem orderItem = cloneVo(orderItemVo, OrderItem.class);
            orderItem.setCommented((byte) 0);
            orderItem.setName(name);
            orderItem.setPrice(originPrice);
            orderItem.setShopId(shopId);
            // 计算折扣
            if (discountRetVoMap.containsKey(orderItemVo.getProductId())) {
                Long discountPrice = discountRetVoMap.get(orderItemVo.getProductId()).getDiscountPrice();
                orderItem.setDiscountPrice(discountPrice);
                orderDiscountPrice += discountPrice * orderItem.getQuantity();
            }
            orderItems.add(orderItem);
        }
        // 计算总折扣
        orderDiscountPrice = Math.round(1.0 * orderDiscountPrice / 10);

        //计算运费
        Long freightPrice = ((FreightCalculatingRetVo) orderItemService.calculateFreight(orderVo.getRegionId(), orderItems).getData()).getFreightPrice();

        //判断所使用的积点是否超过用户的积点,未扣除，仅记录
        CustomerVo customerVo = (CustomerVo) customerService.selectSelf().getData();
        if (customerVo == null)
            return new ReturnObject(ReturnNo.RESOURCE_ID_NOTEXIST);
        Long point = customerVo.getPoint();
        if (point < orderVo.getPoint()){
            orderVo.setPoint(point);
            point=orderVo.getPoint();
        }
        customerService.usePoint(userId, orderVo.getPoint());

        //orderVo.setPoint(100L);
        System.out.println("point:"+orderVo.getPoint());
        //新建订单
        Order order = cloneVo(orderVo, Order.class);
        order.setPid(pId);
        order.setShopId(shopId);
        order.setState(Order.State.CREATED.getCode());
        order.setBeDeleted((byte) 0);
        order.setExpressFee(freightPrice);
        order.setCustomerId(userId);
        order.setOriginPrice(orderOriginPrice);
        order.setDiscountPrice(orderDiscountPrice);
        order.setAdvancesaleId(0L);
        order.setGrouponId(0L);

        //生成订单序号
        Random r = new Random();
        int platform = Math.abs(r.nextInt(36));
        String orderSn = Common.genSeqNum(36);
        order.setOrderSn(orderSn);
        Common.setPoCreatedFields(order, userId, userName);
        order.setGmtCreate(LocalDateTime.now());
        ReturnObject orderRet = orderDao.insertOrder(order);
        if (!orderRet.getCode().equals(ReturnNo.OK)) {
            return orderRet;
        }
        order = cloneVo(orderRet.getData(), Order.class);

        //新建订单详情
        for (OrderItem orderItem : orderItems) {
            orderItem.setOrderId(order.getId());
            orderItem.setPoint((orderItem.getPrice() / order.getOriginPrice()) * order.getPoint());
            Common.setPoCreatedFields(orderItem, userId, userName);
            //新增订单详情
            ReturnObject orderItemRet = orderItemDao.insertOrderItem(orderItem);
            if (!orderItemRet.getCode().equals(ReturnNo.OK)) {
                return orderItemRet;
            }
        }


        Long amount = orderOriginPrice - orderDiscountPrice - orderVo.getPoint() + freightPrice;
        System.out.println("amount:==========================");
        System.out.println("amount:"+amount);
        System.out.println("orderOriginPrice:"+orderOriginPrice);
        System.out.println("orderDiscountPrice:"+orderDiscountPrice);
        System.out.println("point:"+orderVo.getPoint());
        System.out.println("freightPrice:"+freightPrice);

        OrderRetVo orderRetVo = new OrderRetVo(order.getId(), orderOriginPrice, orderDiscountPrice, freightPrice, amount);
        return new ReturnObject(orderRetVo);
    }


    /**
     * 查询订单完整信息
     */
    @Transactional(readOnly = true, rollbackFor = Exception.class)
    public ReturnObject selectOrderInfo(Long id, Long userId) {
        Order order = (Order) orderDao.selectOrderById(id).getData();
        if (order == null)
            return new ReturnObject(ReturnNo.RESOURCE_ID_NOTEXIST);
        if (!order.getCustomerId().equals(userId))
            return new ReturnObject(ReturnNo.RESOURCE_ID_OUTSCOPE);
        List<OrderItem> orderItems = (List) orderItemDao.selectOrderItemsByOrderId(id).getData();
        List<OrderItemSimpleVo> orderItemVos = new ArrayList<>(orderItems.size());
        for (OrderItem bo : orderItems) {
            OrderItemSimpleVo vo = cloneVo(bo, OrderItemSimpleVo.class);
            orderItemVos.add(vo);
        }
        InternalReturnObject<ShopVo> shopVoReturnObject = null;
        InternalReturnObject<SimpleCustomerRetVo> userVoReturnObject = null;
        try {
            userVoReturnObject = customerService.getCustomerById(order.getCustomerId());
            if (order.getShopId() != 0) {
                shopVoReturnObject = shopService.getShopById(order.getShopId());
            }
        } catch (Exception e) {
            return new ReturnObject(ReturnNo.INTERNAL_SERVER_ERR, e.getMessage());
        }


        SimpleCustomerRetVo customer = userVoReturnObject.getData();
        OrderInfoRetVo orderInfoRetVo = cloneVo(order, OrderInfoRetVo.class);
        orderInfoRetVo.setCustomer(new UserVo(customer.getId(), customer.getName()));
        if (null != shopVoReturnObject) {
            ShopVo shop = shopVoReturnObject.getData();
            orderInfoRetVo.setShop(shop);
        }
        orderInfoRetVo.setOrderItem(orderItemVos);
        return new ReturnObject(orderInfoRetVo);
    }

    /**
     * 买家修改本人名下订单
     * 同步修改分单地址
     */
    @Transactional(rollbackFor = Exception.class)
    public ReturnObject updateOrder(Long id, OrderSimpleVo orderSimpleVo, Long userId, String userName, BindingResult bindingResult) {
        Order order = (Order) orderDao.selectOrderById(id).getData();
        if (order == null)
            return new ReturnObject(ReturnNo.RESOURCE_ID_NOTEXIST);
        if (!order.getCustomerId().equals(userId)) {
            return new ReturnObject(ReturnNo.RESOURCE_ID_OUTSCOPE);
        }
        //确保订单未发货
        Integer state = order.getState();
        if (!(state.equals(Order.State.PAID.getCode())
                || state.equals(Order.State.WAITGROUP.getCode())))
            return new ReturnObject(ReturnNo.STATENOTALLOW);
        //检查运费是否与原来一致
        if (!order.getRegionId().equals(orderSimpleVo.getRegionId())) {
            Long freightPrice = getFreight(order, orderSimpleVo.getRegionId());
            if (!freightPrice.equals(order.getExpressFee())) {
                return new ReturnObject(ReturnNo.ORDER_CHANGENOTALLOW);
            }
        }
        //修改订单
        order.setRegionId(orderSimpleVo.getRegionId());
        order.setAddress(orderSimpleVo.getAddress());
        order.setMobile(orderSimpleVo.getMobile());
        order.setConsignee(orderSimpleVo.getConsignee());
        Common.setPoModifiedFields(order, userId, userName);
        ReturnObject returnObject = orderDao.updateOrder(order);
        if (returnObject.getCode().getCode() != 0) {
            return returnObject;
        }
        //如果分单,同步修改子订单
        if (order.getPid().equals(0L)) {
            List<Order> orderList = (List) orderDao.selectChildOrders(id).getData();
            for (Order bo : orderList) {
                bo.setRegionId(orderSimpleVo.getRegionId());
                bo.setAddress(orderSimpleVo.getAddress());
                bo.setMobile(orderSimpleVo.getMobile());
                bo.setConsignee(orderSimpleVo.getConsignee());
                Common.setPoModifiedFields(bo, userId, userName);
                ReturnObject ret = orderDao.updateOrder(bo);
                if (ret.getCode().getCode() != 0) {
                    return ret;
                }
            }
        }
        return returnObject;
    }

    /**
     * 计算某一订单的运费
     */
    public Long getFreight(Order order, Long regionId) {
        Long orderFreight = 0L;
        //如果是父订单，先获得所有子订单运费
        if (order.getPid().equals(0L)) {
            List<Order> orderList = (List) orderDao.selectChildOrders(order.getId()).getData();
            for (Order bo : orderList) {
                List<OrderItem> orderItems = (List) orderItemDao.selectOrderItemsByOrderId(bo.getId()).getData();
                Long freightPrice = ((FreightCalculatingRetVo) orderItemService.calculateFreight(regionId, orderItems).getData()).getFreightPrice();
                orderFreight += freightPrice;
            }
        }
        //否则，直接获得自己的运费
        else {
            List<OrderItem> orderItems = (List) orderItemDao.selectOrderItemsByOrderId(order.getId()).getData();
            Long freightPrice = ((FreightCalculatingRetVo) orderItemService.calculateFreight(regionId, orderItems).getData()).getFreightPrice();
            orderFreight = freightPrice;
        }
        return orderFreight;
    }


    /**
     * 逻辑删除订单
     */
    @Transactional(rollbackFor = Exception.class)
    public ReturnObject deleteOrder(Long id, Long userId, String userName) {
        Order order = (Order) orderDao.selectOrderById(id).getData();
        if (order == null)
            return new ReturnObject(ReturnNo.RESOURCE_ID_NOTEXIST);
        //确保本人名下订单
        if (order.getCustomerId() != userId) {
            return new ReturnObject(ReturnNo.RESOURCE_ID_OUTSCOPE);
        }
        //确保订单完成或取消状态
        Integer state = order.getState();
        if (!(state.equals(Order.State.FINISHED.getCode())
                || state.equals(Order.State.CANCELED.getCode())))
            return new ReturnObject(ReturnNo.STATENOTALLOW);
        //逻辑删除订单
        order.setBeDeleted((byte) 1);
        Common.setPoModifiedFields(order, userId, userName);
        return orderDao.updateOrder(order);
    }

    /**
     * 取消订单
     * 同步取消关联订单
     */
    @Transactional(rollbackFor = Exception.class)
    public ReturnObject cancelOrder(Long id, Long userId, String userName) {
        Order order = (Order) orderDao.selectOrderById(id).getData();
        if (order == null)
            return new ReturnObject(ReturnNo.RESOURCE_ID_NOTEXIST);
        if (!order.getCustomerId().equals(userId)) {
            return new ReturnObject(ReturnNo.RESOURCE_ID_OUTSCOPE);
        }
        //确保订单未完成状态
        Integer state = order.getState();
        if (state.equals(Order.State.FINISHED.getCode()))
            return new ReturnObject(ReturnNo.STATENOTALLOW);
        //取消订单
        order.setState(Order.State.CANCELED.getCode());
        Common.setPoModifiedFields(order, userId, userName);
        ReturnObject returnObject = orderDao.updateOrder(order);
        if (returnObject.getCode().getCode() != 0) {
            return returnObject;
        }

        //增加库存
        //父订单,查找子订单详细信息
        List<Order> orders=(List)orderDao.selectChildOrders(order.getId()).getData();
        if(orders.size()!=0){
            for(Order childOrder:orders){
                List<OrderItem> orderItemList=(List)orderItemDao.selectOrderItemsByOrderId(childOrder.getId()).getData();
                for(OrderItem orderItem:orderItemList){
                    QuantityVo quantityVo = new QuantityVo();
                    quantityVo.setQuantity(orderItem.getQuantity());
                    InternalReturnObject quantityRet = goodsService.incrQuantity(orderItem.getOnsaleId(), quantityVo);
                    if (!quantityRet.getErrno().equals(0)) {
                        return new ReturnObject(ReturnNo.getReturnNoByCode(quantityRet.getErrno()), quantityRet.getErrmsg());
                    }
                }
            }
        }else{
            List<OrderItem> orderItemList=(List)orderItemDao.selectOrderItemsByOrderId(order.getId()).getData();
            for(OrderItem orderItem:orderItemList){
                QuantityVo quantityVo = new QuantityVo();
                quantityVo.setQuantity(orderItem.getQuantity());
                // 取消库存
                InternalReturnObject quantityRet = goodsService.incrQuantity(orderItem.getOnsaleId(), quantityVo);
                if (!quantityRet.getErrno().equals(0)) {
                    return new ReturnObject(ReturnNo.getReturnNoByCode(quantityRet.getErrno()), quantityRet.getErrmsg());
                }
            }
        }

        //如果分单，同步取消子订单
        if (order.getPid().equals(0L)) {
            List<Order> orderList = (List) orderDao.selectChildOrders(id).getData();
            for (Order bo : orderList) {
                bo.setState(Order.State.CANCELED.getCode());
                Common.setPoModifiedFields(bo, userId, userName);
                ReturnObject ret = orderDao.updateOrder(bo);
                if (ret.getCode().getCode() != 0) {
                    return ret;
                }
            }
        }

        // 取消积点
        InternalReturnObject internalReturnObject = customerService.refundPoint(userId, order.getPoint());
        return returnObject;
    }

    /**
     * 买家标记确认收货
     * 同步子订单
     */
    @Transactional(rollbackFor = Exception.class)
    public ReturnObject confirmOrder(Long id, Long userId, String userName) {
        Order order = (Order) orderDao.selectOrderById(id).getData();
        if (order == null)
            return new ReturnObject(ReturnNo.RESOURCE_ID_NOTEXIST);
        if (!order.getCustomerId().equals(userId)) {
            return new ReturnObject(ReturnNo.RESOURCE_ID_OUTSCOPE);
        }
        //确保订单未完成状态
        Integer state = order.getState();
        if (!state.equals(Order.State.DISPATCHED.getCode()))
            return new ReturnObject(ReturnNo.STATENOTALLOW);
        //确认收货
        order.setState(Order.State.FINISHED.getCode());
        Common.setPoModifiedFields(order, userId, userName);
        ReturnObject returnObject = orderDao.updateOrder(order);
        if (returnObject.getCode().getCode() != 0) {
            return returnObject;
        }
        //如果分单，同步对子订单收货
        if (order.getPid().equals(0L)) {
            List<Order> orderList = (List) orderDao.selectChildOrders(id).getData();
            for (Order bo : orderList) {
                order.setState(Order.State.FINISHED.getCode());
                Common.setPoModifiedFields(bo, userId, userName);
                ReturnObject ret = orderDao.updateOrder(bo);
                if (ret.getCode().getCode() != 0) {
                    return ret;
                }
            }
        }
        return returnObject;
    }

//========================================店家================================================

    /**
     * 店家查询商户所有订单 (概要)
     */
    @Transactional(readOnly = true, rollbackFor = Exception.class)
    public ReturnObject selectSimpleOrder(Long shopId, Long customerId, String orderSn, LocalDateTime beginTime, LocalDateTime endTime, Integer page, Integer pageSize) {
        OrderPoExample example = new OrderPoExample();
        OrderPoExample.Criteria criteria = example.createCriteria();
        example.setOrderByClause("gmt_create desc");
        criteria.andShopIdEqualTo(shopId);
        if (orderSn != null)
            criteria.andOrderSnEqualTo(orderSn);
        if (customerId != null)
            criteria.andCustomerIdEqualTo(customerId);
        if (beginTime != null)
            criteria.andGmtCreateGreaterThan(beginTime);
        if (endTime != null)
            criteria.andGmtCreateLessThan(endTime);
        List<Order> orders = (List) orderDao.selectOrders(example).getData();
        if (orders == null)
            return new ReturnObject(ReturnNo.RESOURCE_ID_NOTEXIST);
        List<OrderInfoSimpleVo> orderInfoSimpleVos = new ArrayList<>(orders.size());
        for (Order bo : orders) {
            orderInfoSimpleVos.add(cloneVo(bo, OrderInfoSimpleVo.class));
        }
        PageHelper.startPage(page, pageSize);
        PageInfo<OrderInfoSimpleVo> pageInfo = new PageInfo<OrderInfoSimpleVo>(orderInfoSimpleVos);
        return new ReturnObject(pageInfo);
    }

    /**
     * 店家修改订单 (留言)
     */
    @Transactional(rollbackFor = Exception.class)
    public ReturnObject updateOrder(Long shopId, Long id, OrderMessageVo messageVo, Long userId, String userName) {
        Order order = (Order) orderDao.selectOrderById(id).getData();
        if (order == null)
            return new ReturnObject(ReturnNo.RESOURCE_ID_NOTEXIST);
        //确保店铺内订单
        if (!Objects.equals(order.getShopId(), shopId)) {
            return new ReturnObject(ReturnNo.RESOURCE_ID_OUTSCOPE);
        }
        //更改留言
        order.setMessage(messageVo.getMessage());
        Common.setPoModifiedFields(order, userId, userName);
        return orderDao.updateOrder(order);
    }

    /**
     * 店家查询店内订单完整信息（普通，团购，预售）
     */
    @Transactional(readOnly = true, rollbackFor = Exception.class)
    public ReturnObject selectOrderInfo(Long shopId, Long id, Long userId) {
        Order order = (Order) orderDao.selectOrderById(id).getData();
        if (order == null)
            return new ReturnObject(ReturnNo.RESOURCE_ID_NOTEXIST);
        //确保店铺内订单
        if (!order.getShopId().equals(shopId)) {
            return new ReturnObject(ReturnNo.RESOURCE_ID_OUTSCOPE);
        }
        System.out.println(111);
        //查找订单详情
        List<OrderItem> orderItems = (List) orderItemDao.selectOrderItemsByOrderId(id).getData();
        List<OrderItemSimpleVo> orderItemVos = new ArrayList<>(orderItems.size());
        for (OrderItem orderItem : orderItems) {
            OrderItemSimpleVo vo = cloneVo(orderItem, OrderItemSimpleVo.class);
            orderItemVos.add(vo);
        }
        InternalReturnObject<ShopVo> shopVoReturnObject;
        InternalReturnObject<SimpleCustomerRetVo> userVoReturnObject;
        try {
            shopVoReturnObject = shopService.getShopById(order.getShopId());
            userVoReturnObject = customerService.getCustomerById(order.getCustomerId());
        } catch (Exception e) {
            return new ReturnObject(ReturnNo.INTERNAL_SERVER_ERR, e.getMessage());
        }
        System.out.println(333);
        ShopVo shop = shopVoReturnObject.getData();
        SimpleCustomerRetVo customer = userVoReturnObject.getData();
        System.out.println(customer);
        OrderInfoRetVo orderInfoRetVo = cloneVo(order, OrderInfoRetVo.class);
        orderInfoRetVo.setCustomer(new UserVo(customer.getId(), customer.getName()));
        orderInfoRetVo.setShop(shop);
        orderInfoRetVo.setOrderItem(orderItemVos);
        System.out.println(4554);
        return new ReturnObject(orderInfoRetVo);
    }


    /**
     * 店家对订单标记发货
     */
    @Transactional(rollbackFor = Exception.class)
    public ReturnObject confirmOrder(Long shopId, Long id, OrderShipmentSnVo shipmentSnVo, Long userId, String userName) {
        Order order = (Order) orderDao.selectOrderById(id).getData();
        if (order == null)
            return new ReturnObject(ReturnNo.RESOURCE_ID_NOTEXIST);
        //确保店铺内订单
        if (order.getShopId() != shopId) {
            return new ReturnObject(ReturnNo.RESOURCE_ID_OUTSCOPE);
        }
        //确保订单待发货状态
        Integer state = order.getState();
        if (!(state.equals(Order.State.PAID.getCode())
                || state.equals(Order.State.WAITGROUP.getCode())))
            return new ReturnObject(ReturnNo.STATENOTALLOW);
        //确认发货
        order.setState(Order.State.DISPATCHED.getCode());
        order.setShipmentSn(shipmentSnVo.getShipmentSn());
        Common.setPoModifiedFields(order, userId, userName);
        return orderDao.updateOrder(order);
    }

//--------------------------------------gf----------------------------------------------------------

    /**
     * 管理员创建售后订单
     *
     * @param afterSaleOrderVo
     * @param shopId
     * @param userId
     * @param userName
     * @param bindingResult
     * @return
     */
    @Transactional(readOnly = true, rollbackFor = Exception.class)
    public ReturnObject createVirtualOrder(AfterSaleOrderVo afterSaleOrderVo, long shopId, long userId, String userName, BindingResult bindingResult) {

        //获得请求中的订单明细
        AfterSaleOrderItemVo afterSaleOrderItemVo = afterSaleOrderVo.getOrderItems();

        //需要计算运费的商品List
        ValidList<FreightCalculatingPostVo> afterSaleOrderItemVoList = new ValidList<>();

        //扣库存
        QuantityVo quantityVo = new QuantityVo();
        quantityVo.setQuantity(Long.valueOf(afterSaleOrderItemVo.getQuantity()));
        InternalReturnObject returnObject = goodsService.decreaseOnSale(afterSaleOrderItemVo.getOnsaleId(), quantityVo);
        if (!returnObject.getErrno().equals(0)) {
            return new ReturnObject(ReturnNo.getByCode(returnObject.getErrno()), returnObject.getErrmsg());
        }

        //计算运费
        FreightCalculatingPostVo freightCalculatingPostVo = new FreightCalculatingPostVo();

        //获取运费模板 id、weight
        Long freightId = (goodsService.getFreightModels(shopId, afterSaleOrderItemVo.getProductId()).getData()).getId();
        Integer weight = (goodsService.getProductDetails(afterSaleOrderItemVo.getProductId()).getData()).getWeight().intValue();

        freightCalculatingPostVo.setProductId(afterSaleOrderItemVo.getProductId());
        freightCalculatingPostVo.setFreightId(freightId);
        freightCalculatingPostVo.setWeight(weight);
        afterSaleOrderItemVoList.add(freightCalculatingPostVo);

        //调用FreightService的calculateFreight函数计算运费
        Long freightPrice = (freightService.calculateFreight(afterSaleOrderVo.getRegionId(), afterSaleOrderItemVoList).getData()).getFreightPrice();

        //新建订单和订单明细
        Order order = (Order) cloneVo(afterSaleOrderVo, Order.class);
        OrderItem orderItem = (OrderItem) cloneVo(afterSaleOrderItemVo, OrderItem.class);

        //生成订单序号
        Random r = new Random();
        int platform = Math.abs(r.nextInt(36));
        String orderSn = cn.edu.xmu.privilegegateway.annotation.util.Common.genSeqNum(platform);
        order.setOrderSn(orderSn);

        //订单部分参数
        order.setState(204);
        order.setExpressFee(freightPrice);
        order.setCustomerId(afterSaleOrderVo.getCustomerId());
        order.setOriginPrice(0L);
        order.setDiscountPrice(0L);

        //订单明细参数
        orderItem.setPrice(0L);
        orderItem.setOrderId(order.getId());

        ReturnObject orderRet = orderDao.insertOrder(order);
        if (!orderRet.getCode().equals(ReturnNo.OK)) {
            return orderRet;
        }
        ReturnObject orderItemRet = orderItemDao.insertOrderItem(orderItem);
        if (!orderItemRet.getCode().equals(ReturnNo.OK)) {
            return orderItemRet;
        }

        return new ReturnObject(new AfterSaleOrderRetVo(order, cloneVo(orderItemRet, AfterSaleOrderItemRetVo.class)));

    }

    /**
     * 管理员取消订单
     *
     * @param shopId
     * @param id
     * @return
     */
    @Transactional(readOnly = true, rollbackFor = Exception.class)
    public ReturnObject cancelOrderByAdmin(long shopId, long id) {
        //根据订单id查找订单(父订单)
        Order order = (Order) orderDao.selectOrderById(id).getData();

        //查询是否分单（pid为id的订单）
        OrderPoExample orderPoExample = new OrderPoExample();
        OrderPoExample.Criteria criteria = orderPoExample.createCriteria();
        criteria.andPidEqualTo(id);
        List<Order> subOrderList = orderDao.selectOrders(orderPoExample).getData();

        //父订单pid为0
        //没有分单时，查询是否为团购和预售订单
        if (subOrderList.size() == 0) {
            //参加预售活动时
            if (order.getAdvancesaleId() != 0) {
                //查询所有上线的预售活动
                List<AdvanceSaleRetVo> onlineSaleActivitiesList = (List) advanceSaleService.queryAllOnlineAdvanceSales(order.getShopId(), null, null, null, null, null).getData();
                List<Long> onlineSaleIdList = new ArrayList<>();
                for (AdvanceSaleRetVo advanceSaleRetVo : onlineSaleActivitiesList)
                    onlineSaleIdList.add(advanceSaleRetVo.getId());

                //如果订单中的预售活动仍处于上线状态
                if (onlineSaleIdList.contains(order.getAdvancesaleId())) {
                    //如果订单处于新订单状态 此时没有与订单对应的支付单
                    if (order.getState() == Order.State.CREATED.getCode()) {
                        //将订单状态变为已取消
                        order.setState(Order.State.CANCELED.getCode());

                    }
                    //如果订单处于待支付尾款状态
                    else if (order.getState() == Order.State.OBLIGATION.getCode()) {

                        //将订单状态变为已取消
                        order.setState(Order.State.CANCELED.getCode());

                        //查询支付单 此时存在与订单对应的支付单，支付类型为定金
                        Payment payment = (Payment) paymentService.getOrderPayments(order.getId()).getData();

                        //新建退款单
                        Refund refund = cloneVo(payment, Refund.class);
                        refund.setPatternId(payment.getId());
                        ReturnObject paymentRet = (ReturnObject) paymentService.insertRefund(cloneVo(refund, cn.edu.xmu.oomall.order.microservice.bo.Refund.class)).getData();
                        if (!paymentRet.getCode().equals(ReturnNo.OK)) return paymentRet;
                    }
                    //订单处于付款完成状态 此时订单应该对应定金和尾款两笔支付
                    else if (order.getState() == Order.State.PAID.getCode()) {

                        //将订单状态变为已取消
                        order.setState(Order.State.CANCELED.getCode());

                        //查询支付单 对应两个支付单
                        ReturnObject ret = (ReturnObject) paymentService.getOrderPayments(order.getId()).getData();
                        List<Payment> paymentList = (List<Payment>) ret.getData();

                        //生成退款单 退款单单据类型documentType需要定义枚举类型
                        Refund refund = cloneVo(paymentList.get(0), Refund.class);
                        refund.setAmount(paymentList.get(0).getAmount() + paymentList.get(1).getAmount());
                        ReturnObject paymentRet = (ReturnObject) paymentService.insertRefund(cloneVo(refund, cn.edu.xmu.oomall.order.microservice.bo.Refund.class)).getData();
                        if (!paymentRet.getCode().equals(ReturnNo.OK)) return paymentRet;
                    }
                }
            }

            //订单为普通订单时 只有101和201两个状态
            else {
                //如果订单处于新订单状态 此时没有与订单对应的支付单
                if (order.getState() == Order.State.CREATED.getCode()) {
                    //将订单状态变为已取消
                    order.setState(Order.State.CANCELED.getCode());

                }
                //订单处于付款完成状态
                else if (order.getState() == Order.State.PAID.getCode()) {

                    //将订单状态变为已取消
                    order.setState(Order.State.CANCELED.getCode());

                    //查询支付单
                    Payment payment = (Payment) paymentService.getOrderPayments(order.getId()).getData();

                    //生成退款单 退款单单据类型documentType需要定义枚举类型
                    Refund refund = cloneVo(payment, Refund.class);
                    //退款金额取消快递费
                    refund.setAmount(payment.getActualAmount() - order.getExpressFee());
                    //退用户积点

                    ReturnObject paymentRet = (ReturnObject) paymentService.insertRefund(cloneVo(refund, cn.edu.xmu.oomall.order.microservice.bo.Refund.class)).getData();
                    if (!paymentRet.getCode().equals(ReturnNo.OK)) return paymentRet;
                }
            }
        }
        //分单时，不需要判断团购和预售
        else {

            //如果订单处于新订单状态 此时没有与订单对应的支付单
            if (order.getState() == Order.State.CREATED.getCode()) {
                //将订单状态变为已取消
                order.setState(Order.State.CANCELED.getCode());

            }
            //订单处于付款完成状态
            else if (order.getState() == Order.State.PAID.getCode()) {

                //将订单状态变为已取消
                order.setState(Order.State.CANCELED.getCode());
                for (Order subOrders : subOrderList) subOrders.setState(Order.State.CANCELED.getCode());

                for (Order subOrder : subOrderList) {
                    //查询支付单
                    Payment payment = (Payment) paymentService.getOrderPayments(subOrder.getId()).getData();

                    //生成退款单 退款单单据类型documentType需要定义枚举类型
                    Refund refund = cloneVo(payment, Refund.class);

                    //退款金额取消快递费
                    refund.setAmount(payment.getActualAmount() - order.getExpressFee());
                    //退用户积点

                    ReturnObject paymentRet = (ReturnObject) paymentService.insertRefund(cloneVo(refund, cn.edu.xmu.oomall.order.microservice.bo.Refund.class)).getData();
                    if (!paymentRet.getCode().equals(ReturnNo.OK)) return paymentRet;
                }
            }
        }

        //返回的参数类型 目前只返回returnObject
        return new ReturnObject();
    }

    @Transactional(readOnly = true, rollbackFor = Exception.class)
    public ReturnObject confirmGrouponOrder(long shopId, long id) {
        //根据id查询订单
        Order order = (Order) orderDao.selectOrderById(id).getData();
        OrderItem orderItem = (OrderItem) orderItemDao.selectOrderItemsByOrderId(order.getId()).getData();

        //根据团购规则判断是否满足成团条件
        //查询所有上线的团购活动
        List<GroupOnActivityVo> groupOnActivityVoList = (List<GroupOnActivityVo>) advanceSaleService.queryAllOnlineAdvanceSales(shopId, null, null, null, null, null);
        List<Long> groupOnActivityIdList = new ArrayList<>();

        for (GroupOnActivityVo groupOnActivityVo : groupOnActivityVoList)
            groupOnActivityIdList.add(groupOnActivityVo.getId());

        //订单中的团购活动是否上线
        if (groupOnActivityIdList.contains(order.getGrouponId())) {
            //获得订单中团购活动详细信息
            GroupOnActivityVo orderGroupOnActivity = (GroupOnActivityVo) groupOnActivityService.getOnlineGroupOnActivity(order.getGrouponId());
            List<GroupOnStrategyVo> groupOnStrategyVoList = orderGroupOnActivity.getStrategy();

            //如果不满足团购规则，修改订单状态
            if (orderItem.getQuantity() < groupOnStrategyVoList.get(0).getQuantity())
                order.setState(Order.State.PAID.getCode());

            //如果满足团购规则，则成团，生成退款单，修改订单状态
            for (GroupOnStrategyVo groupOnStrategyVo : groupOnStrategyVoList) {
                if (orderItem.getQuantity() >= groupOnStrategyVo.getQuantity()) {
                    orderItem.setDiscountPrice(orderItem.getPrice() * groupOnStrategyVo.getPercentage());
                    order.setDiscountPrice(orderItem.getDiscountPrice() * orderItem.getQuantity());

                    ReturnObject orderItemRet = orderItemDao.updateOrderItem(orderItem);
                    if (!orderItemRet.getCode().equals(ReturnNo.OK)) return orderItemRet;
                    ReturnObject orderRet = orderDao.updateOrder(order);
                    if (!orderRet.getCode().equals(ReturnNo.OK)) return orderRet;

                    Payment payment = (Payment) paymentService.getOrderPayments(order.getId()).getData();
                    Refund refund = cloneVo(payment, Refund.class);
                    refund.setAmount(payment.getAmount() - order.getExpressFee() - order.getDiscountPrice());

                    ReturnObject paymentRet = (ReturnObject) paymentService.insertRefund(cloneVo(refund, cn.edu.xmu.oomall.order.microservice.bo.Refund.class)).getData();
                    if (!paymentRet.getCode().equals(ReturnNo.OK)) return paymentRet;
                    break;
                }
            }

        }

        return new ReturnObject();


    }

    @Transactional(readOnly = true, rollbackFor = Exception.class)
    public ReturnObject checkOrderPayment(Long id, Long userId, String userName) {
        ReturnObject ret = paymentDao.getPaymentById(id, userId);
        if (ret.getCode().equals(ReturnNo.OK)) {
            List<PaymentPo> paymentPos = (List<PaymentPo>)ret.getData();
            List<PaymentVo> paymentVos = new ArrayList<>();
            for (PaymentPo paymentPo : paymentPos) {
                paymentVos.add(cloneVo(paymentPo, PaymentVo.class));
            }
        }
        return ret;
    }

    // 查询退款
    @Transactional(readOnly = true, rollbackFor = Exception.class)
    public ReturnObject selectRefund(Long id, Long userId, String userName) {
        try {
            Order order = (Order) orderDao.selectOrderById(id).getData();
            if (!order.getCustomerId().equals(userId)) {
                return new ReturnObject(ReturnNo.RESOURCE_ID_OUTSCOPE);
            }
            Order fatherOrder;
            if (order.getPid() != 0) {
                fatherOrder = (Order) orderDao.selectOrderById(order.getPid()).getData();
            } else {
                fatherOrder = order;
            }
            Refund refund = (Refund) refundDao.selectByTradeSn(fatherOrder.getOrderSn()).getData();
            RefundRetVo refundRetVo = cloneVo(refund, RefundRetVo.class);
            List<RefundRetVo> refundRetVoList = new ArrayList<>();
            refundRetVoList.add(refundRetVo);
            return new ReturnObject(refundRetVoList);
        } catch (Exception e) {
            return new ReturnObject(ReturnNo.INTERNAL_SERVER_ERR);
        }
    }
}
